#ifndef __GWSIMPLETYPETRAITS_HPP__
#define __GWSIMPLETYPETRAITS_HPP__

/**
*@file       gwsimpletypetraits.hpp
*@brief      imple type traits class, wrote this for my own purpose
*
*@author     graywind
*@version    1.0.0.0
*@data       2011/12/27
*/

///util stuff
namespace gwBedrockUtil
{
        ///simple type traits
        template<class T>
        class SimpleTypeTraits;
}

///util stuff
namespace gwBedrockUtil
{
        ///simple type traits
        template<class T>
        class gwSimpleTypeTraits
        {
        private:
                template<class V>
                struct ConstTraits
                {
                        typedef V         value_type;
                        enum{   result = false  };
                };

                template<class V>
                struct ConstTraits<const V>
                {
                        typedef V         value_type;
                        enum{   result = true  };
                };

                template<class V>
                struct ReferenceTraits
                {
                        typedef V         value_type;
                        enum{   result = false };
                };

                template<class V>
                struct ReferenceTraits<V&>
                {
                        typedef V         value_type;
                        enum{   result = true  };
                };

                template<class V>
                struct PointeeTraits
                {
                        typedef V         value_type;
                        enum{   result = false  };
                };

                template<class V>
                struct PointeeTraits<V*>
                {
                        typedef typename PointeeTraits<V>::value_type         value_type;
                        enum{   result = true  };
                };

        public:
                enum{  isReference = typename ReferenceTraits<T>::result };
                enum{  isPointee   = typename PointeeTraits<T>::result };
                enum{  isConst     = typename ConstTraits<typename PointeeTraits<typename ReferenceTraits<T>::value_type>::value_type>::result };

                typedef typename ConstTraits<typename PointeeTraits<typename ReferenceTraits<T>::value_type>::value_type>::value_type value_type;
                typedef value_type* pointee_type;
                typedef value_type& reference_type;

        private:
                template<bool IsFast>
                struct ParameterTraits
                {
                        typedef T         parameter_type;
                        enum{  result = true   };
                };

                template<>
                struct ParameterTraits<false>
                {
                        typedef const value_type& parameter_type;
                        enum{  result = false   };
                };

        public:
                enum{ isFastParameter = typename ParameterTraits<isPointee || isReference>::result };

                typedef typename ParameterTraits<isFastParameter>::parameter_type parameter_type;

        };
}
#endif
